package com.ali.business.controler;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ali.util.RedisLockUtil;

/**
 * 
 * @author nning_l@163.com
 * @date 2020年4月10日
 */
@RestController
@RequestMapping("/redission" )
public class RedissonLockController {

	/**
	 * 锁测试共享变量
	 */
	private int lockCount = 10;
	
	/**
	 * 无锁测试共享变量
	 */
	private int count = 10;
	
	/**
	 * 模拟线程数
	 */
	private static int threadNum = 10;
	
	@GetMapping(value = "/test")
	public void lock() {
		final CountDownLatch latch = new CountDownLatch(1);
		for (int i=0; i<threadNum; i++) {
			Thread thread = new Thread(new RedisRunnable(latch));
			thread.start();
		}
		// 释放所有线程
		latch.countDown();
	}
	
	public class RedisRunnable implements Runnable {

		/**
		 * 计数器
		 */
		final CountDownLatch latch;
		
		public RedisRunnable(CountDownLatch latch) {
			this.latch = latch;
		}
		
		@Override
		public void run() {
			try {
				// 阻塞当前线程，直到计时器的值为0
				latch.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			// 无锁操作
			testCount();
			// 加锁操作
			testLockCount();
		}
	}
	
	private void testCount() {
		count--;
		System.out.println("count : "+count);
	}
	
	private void testLockCount() {
		String lockKey = "lock-test";
		try {
			RedisLockUtil.lock(lockKey,2, TimeUnit.SECONDS);
			lockCount--;
			System.out.println("lockCount : "+lockCount);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 释放锁
			RedisLockUtil.unlock(lockKey);
		}
	}
}
